#pragma once

#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include "SocketBase.h"

/////////////////////////////////////////////////
/// \class Socket
///
/// \brief Provide socket operations
///
/// Provide socket operations for socket send, receive data
/// and get sock and peer addresses.
/////////////////////////////////////////////////
class Socket : public SocketBase
{
public:
	Socket();
	virtual ~Socket();

	/////////////////////////////////////////////////
	/// \fn int Init()
	/// \param sock The socket handler
	///
	/// Initialize the socket with a socket handler.
	/// A socket must be initialized before doing other operations.
	/// This function will be called by the server socket when
	/// doing the accept operation.
	/////////////////////////////////////////////////
	void Init(int sock);

	/////////////////////////////////////////////////
	/// \fn int GetSockAddr(sockaddr_in& localaddr)
	/// \param [out] localaddr The socket address.
	/// \return Error code of this operation, zero as success.
	///
	/// Get the socket address.
	/// A socket has two addresses, one is local IP and local port,
	/// another is remote IP and remote port.
	/// This function get the local IP and local port of the socket.
	/////////////////////////////////////////////////
	int GetSockAddr(sockaddr_in& localaddr);

	/////////////////////////////////////////////////
	/// \fn int GetPeerAddr(sockaddr_in& peeraddr)
	/// \param [out] peeraddr The peer address.
	/// \return Error code of this operation, zero as success.
	///
	/// Get the peer address.
	/// A socket has two addresses, one is local IP and local port,
	/// another is remote IP and remote port.
	/// This function get the remote IP and remote port of the socket.
	/////////////////////////////////////////////////
	int GetPeerAddr(sockaddr_in& peeraddr);

	/////////////////////////////////////////////////
	/// \fn int Send(const void* data, int* len)
	/// \param [in] data The buffer to be sent.
	/// \param [in, out] len The data bytes length.  It will be filled with the sent bytes length.
	/// \return Error code of this operation, zero as success.
	///
	/// Send data to the socket.
	/// The data buffer will be sent at most <i>len</i> bytes,
	/// the bytes sent maybe less than <i>len</i> bytes in some condition,
	/// such as the socket has been closed when do the sending operation.
	/////////////////////////////////////////////////
	int Send(const void* data, int* len);

	/////////////////////////////////////////////////
	/// int Receive(void* data, int* len)
	/// \param [out] data The buffer to receive data.
	/// \param [in, out] len The buffer length.  It will be filled with the received bytes length.
	/// \return Error code of this operation, zero as success.
	///
	/// Receive data from the socket.
	/// The data buffer will be filled at most <i>len</i> bytes,
	/// the bytes received maybe less than <i>len</i> bytes.
	/////////////////////////////////////////////////
	int Receive(void* data, int* len);

	/////////////////////////////////////////////////
	/// int ReceiveFully(void* data, int len)
	/// \param [out] data The buffer to receive data.
	/// \param len The length bytes should be received.
	/// \return Error code of this operation, zero as success.
	///
	/// Receive data with <i>len</i> bytes from the socket.
	/// The data buffer will be filled at <i>len</i> bytes if has no errors.
	/////////////////////////////////////////////////
	int ReceiveFully(void* data, int len);
};
